package chapter07._02_CatchException;

import chapter07._01_ExceptionHanding.Test01_HowToThrowException;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @Description: 在catch语句中再次抛出异常 形成异常链
 * @LastDate: 2020/10/22
 */
public class Test03_ThrowInCatchBlock {

    public static void main(String[] args) {
        try {
            Test03_ThrowInCatchBlock.readWithSetOriginalToNew();
        } catch (EOFException e) {
            //包装异常 获取原始异常
            Throwable original = e.getCause();
            System.err.println(original);
        }
    }

    public void readJustLog(String fileName) throws IOException {
        try {
            var in = new FileInputStream(fileName);
            int b;
            while ((b = in.read()) != -1) {
                //do something
            }
        } catch (Exception e) {
            /*
            * 注意 在这里 catch的是Exception类型的异常
            * Java7之前 会提示你应该在方法首部throws Exception而不是IOException
            * 只要try存在的是和方法首部声明的异常类型相同 且在catch中throw的e也是相同类型
            * 就是合法的
            * */
//          有时候只是记录一下异常 不做处理 抛出
            var logger = Logger.getLogger("logger");
            logger.log(Level.parse("lv1"), "JustLog", e);//参数乱写的
            throw e;
        }
    }

    public void readWithThrowAgain(String fileName) throws IOException {
        try {
            var in = new FileInputStream(fileName);
            int b;
            while ((b = in.read()) != -1) {
                //do something
            }
        } catch (IOException e) {
            /*
            * 可以不对异常进行操作 再次throw
            * */
            throw e;
        }
    }

    public static void readWithSetOriginalToNew() throws EOFException {
        try {
            var test = new Test01_HowToThrowException();
            test.readData(new Scanner(Path.of("fundamentals/chapter07/_01_ExceptionHanding/Docs/input")));
        } catch (EOFException original) {
            /*
            * 在catch中抛出异常更好的做法是
            * 把原始异常设置为新异常的起因 再抛出
            * 这样的好处是
            * 捕获到这个新异常时 可以使用getCause()获取原始异常
            * 这样就可以在调用该方法的子系统中，抛出高层异常而不会丢失异常信息
            * 甚至可以把检查型异常包装为运行时异常
            * 详见main方法调用此方法的操作
            * */
            var e = new EOFException();
            e.initCause(original);
            throw e;
        } catch (IOException e) {
            e.getMessage();
        }
    }
}
